<template>
  <div ref="chartRef" :style="{
      width: size.width,
      height: size.height,
      margin: '0 auto',
      border: '1px solid #eee',
      borderRadius: '8px',
      padding: '10px'
    }"></div>
</template>

<script setup>
import { ref, watch, onMounted, onUnmounted, computed } from 'vue';
import * as echarts from 'echarts';

/**
 * Props 定义：接收外部传入的配置和数据
 */
const props = defineProps({
  // 核心数据：[{stockName: 股票名称, holdingRatio: 持仓占比}, ...]
  holdings: {
    type: Array,
    default: () => [],
    validator: (value) => {
      // 校验数据格式：数组内每个元素必须包含 stockName 和 holdingRatio
      return value.every(item =>
        typeof item.stockName === 'string' &&
        typeof item.holdingRatio === 'number'
      );
    }
  },
  // 标签显示阈值（占比≥该值才显示标签，默认10%）
  labelShowThreshold: {
    type: Number,
    default: 10,
    validator: (value) => value >= 0 && value <= 100 // 阈值必须在 0-100 之间
  },
  // 自定义颜色列表（可选）
  colors: {
    type: Array,
    default: () => [
      '#2f54eb', '#1890ff', '#40a9ff', '#69c0ff',
      '#91d5ff', '#b7eb8f', '#fadb14', '#fa8c16', '#ff4d4f'
    ]
  },
  // 容器大小（默认：800px × 500px）
  size: {
    type: Object,
    default: () => ({ width: '800px', height: '500px' }),
    validator: (value) =>
      typeof value.width === 'string' && typeof value.height === 'string'
  }
});

// 图表实例 ref（用于后续操作 ECharts）
const chartRef = ref(null);
let chartInstance = null; // ECharts 实例

/**
 * 计算属性：过滤有效数据 + 格式转换
 * - 过滤 holdingRatio ≤ 0 的无效数据
 * - 转换为 ECharts 所需的 {name, value} 格式
 */
const validChartData = computed(() => {
  if (!Array.isArray(props.holdings)) return []

  return props.holdings
    .filter(item => item.holdingRatio > 0) // 只保留占比>0的数据
    .map(item => ({
      name: item.stockName, // ECharts 饼图要求的 "名称" 字段
      value: item.holdingRatio // ECharts 饼图要求的 "数值" 字段
    }));
});

/**
 * 计算属性：ECharts 完整配置项
 */
const chartOption = computed(() => {
  const hasValidData = validChartData.value.length > 0;

  return {
    // 颜色配置（循环使用）
    color: props.colors,
    // 悬停提示框（核心：显示完整信息）
    tooltip: {
      trigger: 'item',
      padding: 12,
      textStyle: { fontSize: 14 },
      // 自定义悬停内容：股票名称 + 持仓占比（保留2位小数） + 原始值
      formatter: (params) => `
        <div style="text-align: left; line-height: 1.6;">
          <div>股票名称：${params.name}</div>
          <div>持仓占比：${params.percent.toFixed(2)}%</div>
          <div>原始占比值：${params.value}</div>
        </div>
      `
    },
    // 饼图核心配置
    series: [
      {
        name: '持仓占比',
        type: 'pie',
        radius: ['40%', '70%'], // 环形饼图（内半径40%，外半径70%）
        center: ['60%', '55%'], // 右移给图例留空间
        // 数据：有有效数据则用过滤后的数据，否则显示占位
        data: hasValidData
          ? validChartData.value
          : [{ name: '无有效持仓数据', value: 1 }],
        // 标签配置：仅占比≥阈值时显示
        label: {
          show: (params) => {
            return hasValidData && params.percent >= props.labelShowThreshold;
          },
          fontSize: 13,
          color: '#333',
          formatter: '{b}' // 标签仅显示股票名称（简洁）
        },
        // 标签连接线（与标签显示逻辑一致）
        labelLine: {
          show: (params) => {
            return hasValidData && params.percent >= props.labelShowThreshold;
          },
          length: 15,
          length2: 20
        },
        // 空数据时的占位样式（灰色）
        itemStyle: {
          color: (params) => {
            return hasValidData
              ? props.colors[params.dataIndex % props.colors.length] // 颜色循环
              : '#ccc';
          }
        }
      }
    ]
  };
});

/**
 * 初始化图表
 */
const initChart = () => {
  if (!chartRef.value || chartInstance) return;

  // 初始化 ECharts 实例
  chartInstance = echarts.init(chartRef.value);
  // 应用配置项
  chartInstance.setOption(chartOption.value);
};

/**
 * 图表自适应（窗口缩放时）
 */
const handleResize = () => {
  chartInstance?.resize();
};

/**
 * 生命周期钩子：组件挂载时初始化图表 + 绑定 resize 事件
 */
onMounted(() => {
  initChart();
  window.addEventListener('resize', handleResize);
});

/**
 * 生命周期钩子：组件卸载时销毁图表 + 解绑事件（避免内存泄漏）
 */
onUnmounted(() => {
  window.removeEventListener('resize', handleResize);
  chartInstance?.dispose(); // 销毁 ECharts 实例
  chartInstance = null;
});

/**
 * 监听数据变化：当 holdings 或关键配置变化时，更新图表
 */
watch(
  [() => props.holdings, () => props.labelShowThreshold, () => props.colors],
  () => {
    if (chartInstance) {
      chartInstance.setOption(chartOption.value); // 重新设置配置项
    } else {
      initChart(); // 初始化图表
    }
  },
  { deep: true } // 深度监听：监听数组内对象属性变化
);
</script>